#include "RingQueue.hpp"
#include <cstdlib>
#include <unistd.h>
#include "Task.hpp"

//基于环形队列的生产消费模型

void *Productor(void *ringqueue)
{
    // RingQueue<int>* rq = static_cast<RingQueue<int>*>(ringqueue);
    RingQueue<Task> *rq = static_cast<RingQueue<Task> *>(ringqueue);

    while (true) // 不断生产
    {
        // version1
        // int data = rand() % 10 + 1;
        // rq->push(data);
        // printf("生产数据：%d\n", data);
        // sleep(1); // 通过sleep控制生产的速度

        // version2
        //生产任务
        int x = rand() % 100;
        int y = rand() % 10;
        int index = rand() % oper.size();
        Task t(x, y, oper[index], mymath);

        rq->push(t); // 生产
        printf("生产任务：%s\n", t.toTackString().c_str()); // 打印任务
        sleep(1);// 控制生产速度
    }
}

void *Consumer(void *ringqueue)
{
    // RingQueue<int> *rq = static_cast<RingQueue<int> *>(ringqueue);
    RingQueue<Task> *rq = static_cast<RingQueue<Task> *>(ringqueue);

    while (true) // 不断消费
    {
        // version1
        // int data;
        // rq->pop(&data);
        // printf("消费数据：%d\n", data);
        // // sleep(1); // 通过sleep控制消费的速度

        // version2
        Task t;
        rq->pop(&t); // 消费任务(获取任务)
        string result = t(); // 执行任务
        printf("消费任务：%s\n", result.c_str());
        // sleep(1);// 控制消费速度
    }
}

int main()
{
    srand((unsigned int)time(nullptr) ^ getpid());
    RingQueue<Task> *rq = new RingQueue<Task>();

    // 单消费，单生产
    // pthread_t c, p;
    // pthread_create(&p, nullptr, Productor, rq);
    // pthread_create(&c, nullptr, Consumer, rq);

    // pthread_join(p, nullptr);
    // pthread_join(c, nullptr);

    // 多消费，多生产
    pthread_t p[3], c[6]; // 3生产，6消费
    for(int i = 0; i < 3; i++) 
        pthread_create(p+i, nullptr, Productor, rq);
    for(int i = 0; i < 6; i++) 
        pthread_create(c+i, nullptr, Consumer, rq);

    for(int i = 0; i < 3; i++) 
        pthread_join(p[i], nullptr);
    for(int i = 0; i < 6; i++) 
        pthread_join(c[i], nullptr);

    return 0;
}
